package it.tukano.odt;

import it.tukano.check.Todo;
import it.tukano.fun.Tuple2;
import it.tukano.lang.StringExt;
import it.tukano.reflection.MethodExt;
import it.tukano.swingdeco.containers.JPanelExt;
import it.tukano.swingdeco.containers.JToolBarExt;
import it.tukano.swingdeco.controls.JCheckBoxExt;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Properties;
import javax.swing.JPanel;

public abstract class OdtFieldEditor extends JPanel {
    private JToolBarExt toolbar;
    private JCheckBoxExt optionalBox;
    private ArrayList<Component> optionalComponents;
    private Properties properties = new Properties();
    private OdtField owner;

    public OdtFieldEditor() {
        super(new BorderLayout());
    }
    
    public void setOwner(OdtField f) {
        this.owner = f;
    }
    
    public OdtField getOwner() {
        return owner;
    }

    public abstract void setValue(StringExt t);

    public abstract Tuple2<StringExt, String> applyEditorValue(OdtField field, String xml);
    
    public StringExt getEditorValue() {
        Tuple2<StringExt, String> result = applyEditorValue(null, null);
        return result == null ? StringExt.EMPTY : result.getA();
    }
    
    public boolean hasValue() {
        return getEditorValue().isDefined();
    }

    public abstract void clearValue();

    public void hideDefaultLabel() {
        setBorder(null);
    }

    public void setOptional() {
        ArrayList<Component> components = new ArrayList<Component>(Arrays.asList(getComponents()));
        for(int i = 0; i < components.size(); i++) {
            Component c = components.get(i);
            c.setEnabled(false);
            if(c instanceof Container) {
                components.addAll(Arrays.asList(((Container)c).getComponents()));
            }
        }
        optionalComponents = components;
        toolbar.add(optionalBox = new JCheckBoxExt().noFocus().onChange(new MethodExt(this, "updateOptionalComponentsState")));
    }
    
    public void addSideComponent(Component c) {
        createAndInstallToolbar();
        toolbar.add(c);
    }
    
    public void updateOptionalComponentsState() {
        boolean state = optionalBox.isSelected();
        for (Component component : optionalComponents) {
            component.setEnabled(state);
        }
    }
    
    public void addButton(Component c) {
        createAndInstallToolbar();
        toolbar.add(c);
    }
    
    public void removeButton(String componentName) {
        if(toolbar != null) {
            Component[] components = toolbar.getComponents();
            for (int i = 0; i < components.length; i++) {
                Component component = components[i];
                if(componentName.equals(component.getName())) toolbar.remove(component);
            }
        }
    }

    public boolean isChecked() {
        return optionalBox == null ? true
               : optionalBox.isSelected();
    }

    protected void createAndInstallToolbar() {
        if(toolbar == null) {
            toolbar = new JToolBarExt().floatable(false);
            add(new JPanelExt(new BorderLayout(0,0)).append(toolbar, BorderLayout.NORTH), BorderLayout.WEST);
        }
    }

    public void setEditable(boolean b) {
        Todo.implementThis();
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public String getStorableStringValue() {
        return getEditorValue().toString();
    }
    
    public void onValueChange(Runnable task) {
    }
}
